package cave.game;

import java.util.ArrayList;
import cave.game.ActivityEvent;
import android.app.Activity;
import cave.layer.LayerManager;
import cave.renderer.RenderList;
import cave.renderer.RenderMsgQueue;
import cave.renderer.Renderer;
import cave.renderer.TextureManager;
import cave.utils.IntArray;

public class GameRoot {
	
	private Renderer renderer;
	private RenderMsgQueue renderMsgQueue;
	private RenderList renderList;
	private LayerManager layerManager;
	private TextureManager textureManager;
	private GameServices gameServices;
	
	private float lastFrametime = 1.0f/30;
	
	public GameRoot(Renderer renderer, Activity activity) {
		this.renderer = renderer;
		renderMsgQueue = new RenderMsgQueue();
		renderList = new RenderList();
		textureManager = new TextureManager(activity.getResources(), renderMsgQueue);
		gameServices = new GameServices(textureManager, new SharedPreferences(activity, "prefs"));
		layerManager = new LayerManager(gameServices);		
	}
	
	public boolean update(ArrayList<InputEvent> inputEvents, ArrayList<ActivityEvent> activityEvents, float[] orientation) {
		
		long startTime = System.nanoTime();
		
		Orientation.setValues(orientation);
		
		// Update layers
		if(!layerManager.update(lastFrametime, renderList, inputEvents, activityEvents)){
			// No layers
			return false;
		}

		synchronized (renderer) {
			
			// Swap renderlists
			renderList.ready();
			RenderList emptyList = renderer.getRenderList();
			renderer.setRenderList(renderList);
			emptyList.clear();
			renderList = emptyList;
			
			IntArray messages = renderer.syncRenderMsgQueues(renderMsgQueue);
			processRendererMessages(messages);
			messages.clear();
		}
		
		lastFrametime = (float)((System.nanoTime() - startTime) / 1e9);
		
		return true;
	}
	
	private void processRendererMessages(IntArray messages) {
		/* MESSAGES:
		 * 
		 *  - MSG_CONTEXTCREATED
		 *  	0: id
		 *  
		 *  - MSG_RENDERFPS
		 *  	0: id
		 *  	1: fps
		 */
		
		int processed = 0;
		while (processed < messages.size()) {
			switch (messages.get(processed)) {
			
				case Renderer.MSG_CONTEXTCREATED:
					textureManager.reloadAtlases();
					renderMsgQueue.addParam(RenderMsgQueue.MSG_RESOURCESCREATED);

					processed += 1;
					break;

				case Renderer.MSG_RENDERFPS:
					gameServices.getSharedPrefs().addInteger("rfps", messages.get(processed + 1));
					
					
					processed += 2;
					break;
					
			}
		}
		
	}
}
